1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.google.common.collect;
18
19 import static com.google.common.collect.BoundType.CLOSED;
20 import static com.google.common.collect.BoundType.OPEN;
21
22 import com.google.common.annotations.GwtCompatible;
23 import com.google.common.annotations.GwtIncompatible;
24 import com.google.common.collect.Multiset.Entry;
25
26 import java.util.Comparator;
27 import java.util.Iterator;
28 import java.util.NavigableSet;
29 import java.util.NoSuchElementException;
30 import java.util.SortedSet;
31
32 import javax.annotation.Nullable;
33
34
35
36
37
38
39
40 @GwtCompatible(emulated = true)
41 final class SortedMultisets {
42 private SortedMultisets() {
43 }
44
45
46
47
48 static class ElementSet<E> extends Multisets.ElementSet<E> implements
49 SortedSet<E> {
50 private final SortedMultiset<E> multiset;
51
52 ElementSet(SortedMultiset<E> multiset) {
53 this.multiset = multiset;
54 }
55
56 @Override final SortedMultiset<E> multiset() {
57 return multiset;
58 }
59
60 @Override public Comparator<? super E> comparator() {
61 return multiset().comparator();
62 }
63
64 @Override public SortedSet<E> subSet(E fromElement, E toElement) {
65 return multiset().subMultiset(fromElement, CLOSED, toElement, OPEN).elementSet();
66 }
67
68 @Override public SortedSet<E> headSet(E toElement) {
69 return multiset().headMultiset(toElement, OPEN).elementSet();
70 }
71
72 @Override public SortedSet<E> tailSet(E fromElement) {
73 return multiset().tailMultiset(fromElement, CLOSED).elementSet();
74 }
75
76 @Override public E first() {
77 return getElementOrThrow(multiset().firstEntry());
78 }
79
80 @Override public E last() {
81 return getElementOrThrow(multiset().lastEntry());
82 }
83 }
84
85
86
87
88 @GwtIncompatible("Navigable")
89 static class NavigableElementSet<E> extends ElementSet<E> implements NavigableSet<E> {
90 NavigableElementSet(SortedMultiset<E> multiset) {
91 super(multiset);
92 }
93
94 @Override
95 public E lower(E e) {
96 return getElementOrNull(multiset().headMultiset(e, OPEN).lastEntry());
97 }
98
99 @Override
100 public E floor(E e) {
101 return getElementOrNull(multiset().headMultiset(e, CLOSED).lastEntry());
102 }
103
104 @Override
105 public E ceiling(E e) {
106 return getElementOrNull(multiset().tailMultiset(e, CLOSED).firstEntry());
107 }
108
109 @Override
110 public E higher(E e) {
111 return getElementOrNull(multiset().tailMultiset(e, OPEN).firstEntry());
112 }
113
114 @Override
115 public NavigableSet<E> descendingSet() {
116 return new NavigableElementSet<E>(multiset().descendingMultiset());
117 }
118
119 @Override
120 public Iterator<E> descendingIterator() {
121 return descendingSet().iterator();
122 }
123
124 @Override
125 public E pollFirst() {
126 return getElementOrNull(multiset().pollFirstEntry());
127 }
128
129 @Override
130 public E pollLast() {
131 return getElementOrNull(multiset().pollLastEntry());
132 }
133
134 @Override
135 public NavigableSet<E> subSet(
136 E fromElement, boolean fromInclusive, E toElement, boolean toInclusive) {
137 return new NavigableElementSet<E>(multiset().subMultiset(
138 fromElement, BoundType.forBoolean(fromInclusive),
139 toElement, BoundType.forBoolean(toInclusive)));
140 }
141
142 @Override
143 public NavigableSet<E> headSet(E toElement, boolean inclusive) {
144 return new NavigableElementSet<E>(
145 multiset().headMultiset(toElement, BoundType.forBoolean(inclusive)));
146 }
147
148 @Override
149 public NavigableSet<E> tailSet(E fromElement, boolean inclusive) {
150 return new NavigableElementSet<E>(
151 multiset().tailMultiset(fromElement, BoundType.forBoolean(inclusive)));
152 }
153 }
154
155 private static <E> E getElementOrThrow(Entry<E> entry) {
156 if (entry == null) {
157 throw new NoSuchElementException();
158 }
159 return entry.getElement();
160 }
161
162 private static <E> E getElementOrNull(@Nullable Entry<E> entry) {
163 return (entry == null) ? null : entry.getElement();
164 }
165 }